package com.wendy.common.dao.mybatis.mapper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wendy.common.core.context.PageContextHolder;
import com.wendy.common.core.domain.TableDataInfo;
import com.wendy.common.core.page.OrderByItem;
import com.wendy.common.core.page.PageBO;
import com.wendy.common.core.utils.StringUtils;
import com.wendy.utils.spring.MapstructUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

public  class BasePlusService<MAPPER extends BaseMapper<ENTITY> , ENTITY,VO>
        extends ServiceImpl<MAPPER ,ENTITY> implements IService<ENTITY> {

    protected Class<VO> currentVoClass() {
        return (Class<VO>) ReflectionKit.getSuperClassGenericType(this.getClass(), BasePlusService.class, 2);
    }

    protected Class<ENTITY> currentModelClass() {
        return (Class<ENTITY>) ReflectionKit.getSuperClassGenericType(this.getClass(), BasePlusService.class, 1);
    }

    protected VO getVoById(Serializable id) {
        return getVoById(id, this.currentVoClass());
    }

    /**
     * 根据 ID 查询
     */
    protected <C> C  getVoById(Serializable id, Class<C> voClass) {
        ENTITY obj = super.getById(id);
        if (ObjectUtil.isNull(obj)) {
            return null;
        }
        return MapstructUtils.convert(obj, voClass);
    }

    protected List<VO> selectVoBatchIds(Collection<? extends Serializable> idList) {
        return selectVoBatchIds(idList, this.currentVoClass());
    }

    /**
     * 查询（根据ID 批量查询）
     */
    protected <C> List<C> selectVoBatchIds(Collection<? extends Serializable> idList, Class<C> voClass) {
        List<ENTITY> list = baseMapper.selectBatchIds(idList);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return MapstructUtils.convert(list, voClass);
    }

    /**
     * 根据 entity 条件，查询一条记录
     */
    protected <C> C selectVoOne(Wrapper<ENTITY> wrapper, Class<C> voClass) {
        ENTITY obj = baseMapper.selectOne(wrapper);
        if (ObjectUtil.isNull(obj)) {
            return null;
        }
        return MapstructUtils.convert(obj, voClass);
    }

    protected List<VO> queryVoList() {
        return queryVoList(new QueryWrapper<>(), this.currentVoClass());
    }

    protected List<VO> queryVoList(Wrapper<ENTITY> wrapper) {
        return queryVoList(wrapper, this.currentVoClass());
    }

    /**
     * 根据 entity 条件，查询全部记录
     */
    protected <C> List<C> queryVoList(Wrapper<ENTITY> wrapper, Class<C> voClass) {
        List<ENTITY> list = baseMapper.selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return MapstructUtils.convert(list, voClass);
    }



    protected <P extends IPage<VO>> P queryVoPage(IPage<ENTITY> page, Wrapper<ENTITY> wrapper) {
        return queryVoPage(page, wrapper, this.currentVoClass());
    }

    protected <P extends IPage<VO>> P queryContextVoPage(Wrapper<ENTITY> wrapper) {
        Page<ENTITY> page = getEntityPage();
        return queryVoPage(page, wrapper, this.currentVoClass());
    }

    protected  <ENTITY> Page<ENTITY> getEntityPage() {
        PageBO pageBO=PageContextHolder.get();
        Page<ENTITY> page = new Page<ENTITY>(pageBO.getPageNum(),pageBO.getPageSize());
        List<OrderByItem> list = pageBO.orderByItems;
        if(list!=null && list.size()>0){
                for(OrderByItem orderByItem:list){
                    OrderItem item = new OrderItem();
                    item.setColumn(orderByItem.getColumn());
                    item.setAsc(orderByItem.getIsAsc());
                    page.addOrder(item);
                }
            }
        return page;
    }

    protected TableDataInfo<VO> queryContextTableInfoVoPage( Wrapper<ENTITY> wrapper) {
        PageBO pageBO=PageContextHolder.get();
        Page<ENTITY> page = new Page<ENTITY>(pageBO.getPageNum(),pageBO.getPageSize());
        if(StringUtils.isNotEmpty(pageBO.getOrderByColumn())){
            OrderItem item = new OrderItem();
            item.setColumn(pageBO.getOrderByColumn());
            item.setAsc("ASC".equals(StringUtils.upperCase(pageBO.getIsAsc())));
            page.addOrder(item);
        }
        IPage<VO>  resultPage= queryVoPage(page, wrapper, this.currentVoClass());
        return new TableDataInfo<VO>(resultPage.getRecords(), resultPage.getTotal(),resultPage.getSize(),resultPage.getCurrent());
    }

    protected TableDataInfo<VO> exchangeTableInfoVoPage(Page<ENTITY> resultPage) {
        List<VO> result = MapstructUtils.convert(resultPage.getRecords(), currentVoClass());
        return new TableDataInfo<VO>(result, resultPage.getTotal(),resultPage.getSize(),resultPage.getCurrent());
    }

    protected TableDataInfo<VO> queryTableInfoVoPage(IPage<ENTITY> page, Wrapper<ENTITY> wrapper) {
        IPage<VO>  resultPage= queryVoPage(page, wrapper, this.currentVoClass());
        return new TableDataInfo<VO>(resultPage.getRecords(), resultPage.getTotal(),resultPage.getSize(),resultPage.getCurrent());
    }

    /**
     * 分页查询VO
     */
    protected <C, P extends IPage<C>> P queryVoPage(IPage<ENTITY> page, Wrapper<ENTITY> wrapper, Class<C> voClass) {
        List<ENTITY> list = baseMapper.selectList(page, wrapper);
        IPage<C> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        if (CollUtil.isEmpty(list)) {
            return (P) voPage;
        }
        voPage.setRecords(MapstructUtils.convert(list, voClass));
        return (P) voPage;
    }



}
